package PrjWsMQ

/***
  使用的非字符串头的协议.
*/

import (
	"bytes"
	"dgo/goutils/utils"
	"golang.org/x/net/websocket"
	"net/http"
	"strings"
)

type WsMQServer struct {
	sc *utils.SubscribeCenter
}

func NewWsMQServerWithMux(ws_req_url string, mux *http.ServeMux) *WsMQServer {
	rval := &WsMQServer{
		sc: utils.NewSubscribeCenter(),
	}
	rval.sc.ConfigASyncDispatch(true)
	rval.sc.DispMode = 1
	mux.Handle(ws_req_url, websocket.Handler(rval.onHttpHandle))
	rval.sc.SubscribeChannel(MQ_CHANNEL_CMD, MQ_CHANNEL_CMD, rval.onRecvCmd)
	return rval
}

func NewWsMQServer(ws_req_url string) *WsMQServer {
	return NewWsMQServerWithMux(ws_req_url, http.DefaultServeMux)
}

func (this *WsMQServer) DispatchMessage(channelid string, data interface{}) {
	this.sc.DispatchData(channelid, nil, data, nil)
}

func (this *WsMQServer) onRecvCmd(sender interface{}, channelid string, subscribeid interface{}, data interface{}, tag interface{}, isBreak *bool) bool {
	if sender == nil {
		utils.Log.Warnf("命令没有Sender")
		return true
	}
	wsconn := sender.(*WsSvrConn)
	cmdstr := data.(string)
	cmdstr = strings.TrimPrefix(cmdstr, "/cmd,")
	cmdstrs := strings.SplitN(cmdstr, ",", 2)
	if cmdstrs[0] == "subscrible" {
		if len(cmdstrs) > 1 {
			wsconn.SubscribleChannel(cmdstrs[1])
		}
	}
	return true
}

func (this *WsMQServer) onHttpHandle(ws *websocket.Conn) {
	wsconn := NewWsSvrConn(ws, this)
	defer wsconn.onClose()
	utils.Log.DebugTypef("WsMQ", "连接进入:%s", wsconn.RemoteAddr())
	for {
		msgtype, msg, err := ReceiveMessage(wsconn.conn)
		if err != nil {
			utils.Log.DebugTypef("WsMQ", "接收消息出现异常:%s", err.Error())
			break
		}

		if msgtype == WS_MESSAGE_TEXT {
			str := string(msg)
			strs := strings.SplitN(str, ",", 2)
			if len(strs) > 1 {
				// 发送源数据, 带有ChannelID
				n := this.sc.DispatchData(strs[0], wsconn, str, nil)
				if n == -1 {
					utils.Log.WarnTypef("WsMQ", "[%s]分发数据失败, 同一通道多线程并发Dispatch!", wsconn.RemoteAddr())
				}

			}
		} else if msgtype == WS_MESSAGE_BINARY { // BinaryMessage
			nbuf := bytes.SplitN(msg, buf_spliter, 2)
			id := string(nbuf[0])
			if len(nbuf) > 1 {
				// 发送源数据, 带有ChannelID
				n := this.sc.DispatchData(id, wsconn, msg, nil)
				if n == -1 {
					utils.Log.WarnTypef("WsMQ", "[%s]分发数据失败, 同一通道多线程并发Dispatch!", wsconn.RemoteAddr())
				}
			}
		}
	}

}
